const tencentcloud = require('tencentcloud-sdk-nodejs');
const TtsClient = tencentcloud.tts.v20190823.Client;
const fs = require('fs').promises;
const path = require('path');
const logger = require('../utils/logger');
const config = require('../config');

/**
 * 文本转语音服务
 * 使用腾讯云TTS服务进行文本转语音
 */
class TtsService {
  constructor() {
    this.client = null;
    this.initialized = false;
    this.outputDir = path.join(__dirname, '../../', 'backend/uploads/tts');
  }

  /**
   * 初始化文本转语音服务
   */
  async init() {
    try {
      // 检查配置
      if (!config.tencentCloud.secretId || !config.tencentCloud.secretKey) {
        logger.warn('腾讯云API密钥未配置，文本转语音服务未初始化');
        return;
      }

      // 创建TTS客户端
      const clientConfig = {
        credential: {
          secretId: config.tencentCloud.secretId,
          secretKey: config.tencentCloud.secretKey,
        },
        region: config.tencentCloud.region,
        profile: {
          httpProfile: {
            endpoint: "tts.tencentcloudapi.com",
          },
        },
      };

      this.client = new TtsClient(clientConfig);
      
      // 确保输出目录存在
      await fs.mkdir(this.outputDir, { recursive: true });
      
      this.initialized = true;
      logger.info('文本转语音服务初始化成功');
    } catch (error) {
      logger.error(`文本转语音服务初始化失败: ${error.message}`);
    }
  }

  /**
   * 检查服务是否已初始化
   * @returns {boolean} 是否已初始化
   */
  isInitialized() {
    return this.initialized && this.client !== null;
  }

  /**
   * 将文本转换为语音
   * @param {string} text - 要转换的文本
   * @param {Object} options - 转换选项
   * @returns {Promise<Object>} 包含音频URL和Base64数据的对象
   */
  async textToSpeech(text, options = {}) {
    if (!this.isInitialized()) {
      throw new Error('文本转语音服务未初始化');
    }

    try {
      // 限制文本长度
      if (text.length > 500) {
        logger.warn(`文本长度超过限制，已截断: ${text.length} > 500`);
        text = text.substring(0, 500);
      }

      // 准备请求参数
      const params = {
        Text: text,
        SessionId: options.sessionId || `tts_${Date.now()}`,
        VoiceType: options.voiceType !== undefined ? options.voiceType : config.tts.voiceType,
        Volume: options.volume !== undefined ? options.volume : config.tts.volume,
        Speed: options.speed !== undefined ? options.speed : config.tts.speed,
        ProjectId: options.projectId !== undefined ? options.projectId : config.tts.projectId,
        ModelType: options.modelType !== undefined ? options.modelType : config.tts.modelType,
        PrimaryLanguage: options.primaryLanguage || 1, // 1-中文，2-英文
        SampleRate: options.sampleRate || 16000, // 采样率
        Codec: options.codec || 'mp3', // 音频格式
      };

      // 发送转换请求
      logger.debug(`发送文本转语音请求: "${text.substring(0, 30)}..."`);
      const response = await this.client.TextToVoice(params);

      // 处理响应
      if (response && response.Audio) {
        // 生成唯一文件名
        const fileName = `tts_${Date.now()}_${Math.floor(Math.random() * 1000)}.mp3`;
        const filePath = path.join(this.outputDir, fileName);
        
        // 将Base64音频数据写入文件
        const audioBuffer = Buffer.from(response.Audio, 'base64');
        await fs.writeFile(filePath, audioBuffer);
        
        // 构建音频URL
        const audioUrl = `/uploads/tts/${fileName}`;
        
        logger.debug(`文本转语音成功，文件保存为: ${filePath}`);
        
        return {
          url: audioUrl,
          base64: response.Audio,
          sessionId: response.SessionId
        };
      } else {
        logger.warn('文本转语音结果为空');
        throw new Error('文本转语音结果为空');
      }
    } catch (error) {
      logger.error(`文本转语音失败: ${error.message}`);
      throw error;
    }
  }

  /**
   * 批量处理文本转语音
   * @param {Array<string>} textArray - 要转换的文本数组
   * @param {Object} options - 转换选项
   * @returns {Promise<Array<Object>>} 包含音频URL和Base64数据的对象数组
   */
  async batchTextToSpeech(textArray, options = {}) {
    if (!Array.isArray(textArray) || textArray.length === 0) {
      throw new Error('无效的文本数组');
    }

    const results = [];
    const sessionId = `batch_tts_${Date.now()}`;

    // 为每个文本生成语音
    for (let i = 0; i < textArray.length; i++) {
      try {
        const text = textArray[i];
        // 使用相同的会话ID以保持语音的一致性
        const result = await this.textToSpeech(text, { 
          ...options, 
          sessionId 
        });
        results.push(result);
      } catch (error) {
        logger.error(`批量文本转语音失败，索引 ${i}: ${error.message}`);
        // 添加错误结果
        results.push({ error: error.message, index: i });
      }
    }

    return results;
  }

  /**
   * 清理过期的TTS音频文件
   * @param {number} maxAgeHours - 文件最大保存时间（小时）
   */
  async cleanupOldFiles(maxAgeHours = 24) {
    try {
      if (!this.initialized) {
        await this.init();
      }

      const files = await fs.readdir(this.outputDir);
      const now = Date.now();
      let deletedCount = 0;

      for (const file of files) {
        if (file.startsWith('tts_')) {
          const filePath = path.join(this.outputDir, file);
          const stats = await fs.stat(filePath);
          
          // 检查文件是否过期
          const fileAgeHours = (now - stats.mtimeMs) / (1000 * 60 * 60);
          if (fileAgeHours > maxAgeHours) {
            await fs.unlink(filePath);
            deletedCount++;
          }
        }
      }

      if (deletedCount > 0) {
        logger.info(`已清理 ${deletedCount} 个过期的TTS音频文件`);
      }
    } catch (error) {
      logger.error(`清理TTS音频文件失败: ${error.message}`);
    }
  }
}

// 导出单例
module.exports = new TtsService();